home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / dockedapp.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-16  |  12.4 KB  |  452 lines

  1. /* dockedapp.c- docked application settings panel
  2.  *
  3.  *  Window Maker window manager
  4.  *
  5.  *  Copyright (c) 1998 Alfredo K. Kojima
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  20.  *  USA.
  21.  */
  22.  
  23.  
  24. #include "wconfig.h"
  25.  
  26. #include <X11/Xlib.h>
  27. #include <X11/Xutil.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30.  
  31. #include "WindowMaker.h"
  32. #include "wcore.h"
  33. #include "window.h"
  34. #include "icon.h"
  35. #include "appicon.h"
  36. #include "dock.h"
  37. #include "dialog.h"
  38. #include "funcs.h"
  39. #include "defaults.h"
  40. #include "framewin.h"
  41.  
  42.  
  43. /**** Global variables ****/
  44. extern WPreferences wPreferences;
  45.  
  46.  
  47.  
  48. typedef struct _AppSettingsPanel {
  49.     WMWindow *win;
  50.     WAppIcon *editedIcon;
  51.  
  52.     WWindow *wwin;
  53.  
  54.     WMLabel *iconLabel;
  55.     WMLabel *nameLabel;
  56.  
  57.     WMFrame *commandFrame;
  58.     WMTextField *commandField;
  59.  
  60.     WMFrame *dndCommandFrame;
  61.     WMTextField *dndCommandField;
  62.     WMLabel *dndCommandLabel;
  63.  
  64.     WMFrame *iconFrame;
  65.     WMTextField *iconField;
  66.     WMButton *browseBtn;
  67.  
  68.     WMButton *autoLaunchBtn;
  69.     WMButton *lockBtn;
  70.  
  71.     WMButton *okBtn;
  72.     WMButton *cancelBtn;
  73.  
  74.     Window parent;
  75.  
  76.     /* kluge */
  77.     unsigned int destroyed:1;
  78.     unsigned int choosingIcon:1;
  79. } AppSettingsPanel;
  80.  
  81.  
  82. void DestroyDockAppSettingsPanel(AppSettingsPanel *panel);
  83.  
  84.  
  85. static void
  86. updateCommand(WAppIcon *icon, char *command)
  87. {
  88.     if (icon->command)
  89.     free(icon->command);
  90.     if (command && (command[0]==0 || (command[0]=='-' && command[1]==0))) {
  91.     free(command);
  92.     command = NULL;
  93.     }
  94.     icon->command = command;
  95.  
  96.     if (!icon->wm_class && !icon->wm_instance && icon->command
  97.     && strlen(icon->command)>0) {
  98.     icon->forced_dock = 1;
  99.     }
  100. }
  101.  
  102.  
  103. #ifdef OFFIX_DND
  104. static void
  105. updateDNDCommand(WAppIcon *icon, char *command)
  106. {
  107.     if (icon->dnd_command)
  108.     free(icon->dnd_command);
  109.     if (command && (command[0]==0 || (command[0]=='-' && command[1]==0))) {
  110.     free(command);
  111.     command = NULL;
  112.     }
  113.     icon->dnd_command = command;
  114. }
  115. #endif /* OFFIX_DND */
  116.  
  117.  
  118. static void
  119. updateSettingsPanelIcon(AppSettingsPanel *panel)
  120. {
  121.     char *file;
  122.  
  123.     file = WMGetTextFieldText(panel->iconField);
  124.     if (!file)
  125.     WMSetLabelImage(panel->iconLabel, NULL);
  126.     else {
  127.     char *path;
  128.  
  129.     path = FindImage(wPreferences.icon_path, file);
  130.     if (!path) {
  131.         wwarning(_("could not find icon %s, used in a docked application"),
  132.              file);
  133.         free(file);
  134.         WMSetLabelImage(panel->iconLabel, NULL);
  135.         return;
  136.     } else {
  137.         WMPixmap *pixmap;
  138.         RColor color;
  139.  
  140.         color.red = 0xae;
  141.         color.green = 0xaa;
  142.         color.blue = 0xae;
  143.         color.alpha = 0;
  144.         pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win),
  145.                            path, &color);
  146.         if (!pixmap) {
  147.         WMSetLabelImage(panel->iconLabel, NULL);
  148.         } else {
  149.         WMSetLabelImage(panel->iconLabel, pixmap);
  150.         WMReleasePixmap(pixmap);
  151.         }
  152.     }
  153.     free(file);
  154.     free(path);
  155.     }
  156. }
  157.  
  158.  
  159. static void
  160. chooseIconCallback(WMWidget *self, void *clientData)
  161. {
  162.     char *file;
  163.     AppSettingsPanel *panel = (AppSettingsPanel*)clientData;
  164.     int result;
  165.  
  166.     panel->choosingIcon = 1;
  167.  
  168.     WMSetButtonEnabled(panel->browseBtn, False);
  169.  
  170.     result = wIconChooserDialog(panel->wwin->screen_ptr, &file,
  171.                 panel->editedIcon->wm_instance,
  172.                 panel->editedIcon->wm_class);
  173.  
  174.     panel->choosingIcon = 0;
  175.     if (!panel->destroyed) {
  176.     if (result) {
  177.         WMSetTextFieldText(panel->iconField, file);
  178.         free(file);
  179.         updateSettingsPanelIcon(panel);
  180.     }
  181.  
  182.     WMSetButtonEnabled(panel->browseBtn, True);
  183.     } else {
  184.     /* kluge for the case, the user asked to close the panel before
  185.      * the icon chooser */
  186.     DestroyDockAppSettingsPanel(panel);
  187.     }
  188. }
  189.  
  190.  
  191. static void
  192. panelBtnCallback(WMWidget *self, void *data)
  193. {
  194.     WMButton *btn = self;
  195.     AppSettingsPanel *panel = (AppSettingsPanel*)data;
  196.     char *text;
  197.     int done;
  198.  
  199.     done = 1;
  200.     if (panel->okBtn == btn) {
  201.     text = WMGetTextFieldText(panel->iconField);
  202.     if (text[0]==0) {
  203.         free(text);
  204.         text = NULL;
  205.     }
  206.     if (!wIconChangeImageFile(panel->editedIcon->icon, text)) {
  207.         char *buf;
  208.  
  209.         buf = wmalloc(strlen(text) + 64);
  210.         sprintf(buf, _("Could not open specified icon file: %s"), text);
  211.         if (wMessageDialog(panel->wwin->screen_ptr, _("Error"), buf,
  212.                    _("OK"), _("Ignore"), NULL) == WAPRDefault) {
  213.         if (text)
  214.             free(text);
  215.         free(buf);
  216.         return;
  217.         }
  218.         free(buf);
  219.     } else {
  220.         WAppIcon *aicon = panel->editedIcon;
  221.  
  222.         if (aicon == aicon->icon->core->screen_ptr->clip_icon)
  223.         wClipIconPaint(aicon);
  224.         else
  225.         wAppIconPaint(aicon);
  226.  
  227.         wDefaultChangeIcon(panel->wwin->screen_ptr, aicon->wm_instance,
  228.                    aicon->wm_class, text);
  229.     }
  230.     if (text)
  231.         free(text);
  232.  
  233.     /* cannot free text from this, because it will be not be duplicated
  234.      * in updateCommand */
  235.     text = WMGetTextFieldText(panel->commandField);
  236.     if (text[0]==0) {
  237.         free(text);
  238.         text = NULL;
  239.     }
  240.     updateCommand(panel->editedIcon, text);
  241. #ifdef OFFIX_DND
  242.     /* cannot free text from this, because it will be not be duplicated
  243.      * in updateDNDCommand */
  244.     text = WMGetTextFieldText(panel->dndCommandField);
  245.     updateDNDCommand(panel->editedIcon, text);
  246. #endif
  247.  
  248.     panel->editedIcon->auto_launch =
  249.         WMGetButtonSelected(panel->autoLaunchBtn);
  250.  
  251.     panel->editedIcon->lock =
  252.         WMGetButtonSelected(panel->lockBtn);
  253.     }
  254.  
  255.     if (done)
  256.     DestroyDockAppSettingsPanel(panel);
  257. }
  258.  
  259.  
  260. #define PWIDTH    295
  261. #define PHEIGHT    365
  262.  
  263.  
  264. void
  265. ShowDockAppSettingsPanel(WAppIcon *aicon)
  266. {
  267.     AppSettingsPanel *panel;
  268.     WScreen *scr = aicon->icon->core->screen_ptr;
  269.     Window parent;
  270.     WMFont *font;
  271.     int x, y;
  272.  
  273.     panel = wmalloc(sizeof(AppSettingsPanel));
  274.     memset(panel, 0, sizeof(AppSettingsPanel));
  275.  
  276.     panel->editedIcon = aicon;
  277.  
  278.     aicon->panel = panel;
  279.     aicon->editing = 1;
  280.  
  281.     panel->win = WMCreateWindow(scr->wmscreen, "applicationSettings");
  282.     WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
  283.  
  284.     panel->iconLabel = WMCreateLabel(panel->win);
  285.     WMResizeWidget(panel->iconLabel, 64, 64);
  286.     WMMoveWidget(panel->iconLabel, 10, 10);
  287.     WMSetLabelImagePosition(panel->iconLabel, WIPImageOnly);
  288.  
  289.     panel->nameLabel = WMCreateLabel(panel->win);
  290.     WMResizeWidget(panel->nameLabel, 190, 18);
  291.     WMMoveWidget(panel->nameLabel, 80, 35);
  292.     WMSetLabelTextAlignment(panel->nameLabel, WALeft);
  293.     font = WMBoldSystemFontOfSize(scr->wmscreen, 14);
  294.     WMSetLabelFont(panel->nameLabel, font);
  295.     WMReleaseFont(font);
  296.     if (aicon->wm_class && strcmp(aicon->wm_class, "DockApp")==0)
  297.     WMSetLabelText(panel->nameLabel, aicon->wm_instance);
  298.     else
  299.     WMSetLabelText(panel->nameLabel, aicon->wm_class);
  300.  
  301.     panel->autoLaunchBtn = WMCreateSwitchButton(panel->win);
  302.     WMResizeWidget(panel->autoLaunchBtn, PWIDTH-30, 20);
  303.     WMMoveWidget(panel->autoLaunchBtn, 15, 80);
  304.     WMSetButtonText(panel->autoLaunchBtn,
  305.             _("Start when WindowMaker is started"));
  306.     WMSetButtonSelected(panel->autoLaunchBtn, aicon->auto_launch);
  307.  
  308.     panel->lockBtn = WMCreateSwitchButton(panel->win);
  309.     WMResizeWidget(panel->lockBtn, PWIDTH-30, 20);
  310.     WMMoveWidget(panel->lockBtn, 15, 100);
  311.     WMSetButtonText(panel->lockBtn,
  312.             _("Lock (prevent accidental removal)"));
  313.     WMSetButtonSelected(panel->lockBtn, aicon->lock);
  314.  
  315.     panel->commandFrame = WMCreateFrame(panel->win);
  316.     WMResizeWidget(panel->commandFrame, 275, 50);
  317.     WMMoveWidget(panel->commandFrame, 10, 125);
  318.     WMSetFrameTitle(panel->commandFrame, _("Application path and arguments"));
  319.  
  320.     panel->commandField = WMCreateTextField(panel->commandFrame);
  321.     WMResizeWidget(panel->commandField, 256, 20);
  322.     WMMoveWidget(panel->commandField, 10, 20);
  323.     WMSetTextFieldText(panel->commandField, aicon->command);
  324.  
  325.     panel->dndCommandFrame = WMCreateFrame(panel->win);
  326.     WMResizeWidget(panel->dndCommandFrame, 275, 70);
  327.     WMMoveWidget(panel->dndCommandFrame, 10, 185);
  328.     WMSetFrameTitle(panel->dndCommandFrame,
  329.            _("Command for files dropped with DND"));
  330.  
  331.     panel->dndCommandField = WMCreateTextField(panel->dndCommandFrame);
  332.     WMResizeWidget(panel->dndCommandField, 256, 20);
  333.     WMMoveWidget(panel->dndCommandField, 10, 20);
  334.  
  335.     panel->dndCommandLabel = WMCreateLabel(panel->dndCommandFrame);
  336.     WMResizeWidget(panel->dndCommandLabel, 256, 18);
  337.     WMMoveWidget(panel->dndCommandLabel, 10, 45);
  338. #ifdef OFFIX_DND
  339.     WMSetTextFieldText(panel->dndCommandField, aicon->dnd_command);
  340.     WMSetLabelText(panel->dndCommandLabel,
  341.            _("%d will be replaced with the file name"));
  342. #else
  343.     WMSetTextFieldEditable(panel->dndCommandField, False);
  344.     WMSetLabelText(panel->dndCommandLabel,
  345.            _("DND support was not compiled in"));
  346. #endif
  347.  
  348.     panel->iconFrame = WMCreateFrame(panel->win);
  349.     WMResizeWidget(panel->iconFrame, 275, 50);
  350.     WMMoveWidget(panel->iconFrame, 10, 265);
  351.     WMSetFrameTitle(panel->iconFrame, _("Icon Image"));
  352.  
  353.     panel->iconField = WMCreateTextField(panel->iconFrame);
  354.     WMResizeWidget(panel->iconField, 176, 20);
  355.     WMMoveWidget(panel->iconField, 10, 20);
  356.     WMSetTextFieldText(panel->iconField,
  357.                wDefaultGetIconFile(scr, aicon->wm_instance,
  358.                        aicon->wm_class, True));
  359.  
  360.     panel->browseBtn = WMCreateCommandButton(panel->iconFrame);
  361.     WMResizeWidget(panel->browseBtn, 70, 24);
  362.     WMMoveWidget(panel->browseBtn, 195, 18);
  363.     WMSetButtonText(panel->browseBtn, _("Browse..."));
  364.     WMSetButtonAction(panel->browseBtn, chooseIconCallback, panel);
  365.  
  366.  
  367.     panel->okBtn = WMCreateCommandButton(panel->win);
  368.     WMResizeWidget(panel->okBtn, 80, 26);
  369.     WMMoveWidget(panel->okBtn, 200, 328);
  370.     WMSetButtonText(panel->okBtn, _("OK"));
  371.     WMSetButtonAction(panel->okBtn, panelBtnCallback, panel);
  372.  
  373.     panel->cancelBtn = WMCreateCommandButton(panel->win);
  374.     WMResizeWidget(panel->cancelBtn, 80, 26);
  375.     WMMoveWidget(panel->cancelBtn, 110, 328);
  376.     WMSetButtonText(panel->cancelBtn, _("Cancel"));
  377.     WMSetButtonAction(panel->cancelBtn, panelBtnCallback, panel);
  378.  
  379.     WMRealizeWidget(panel->win);
  380.     WMMapSubwidgets(panel->win);
  381.     WMMapSubwidgets(panel->commandFrame);
  382.     WMMapSubwidgets(panel->dndCommandFrame);
  383.     WMMapSubwidgets(panel->iconFrame);
  384.  
  385.     updateSettingsPanelIcon(panel);
  386.  
  387.     parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
  388.                  0, 0, 0);
  389.     XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
  390.  
  391.     XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
  392.  
  393.     y = aicon->y_pos;
  394.     if (y < 0)
  395.     y = 0;
  396.     else if (y + PWIDTH > scr->scr_height)
  397.     y = scr->scr_height - PHEIGHT - 30;
  398.  
  399.     if (aicon->dock && aicon->dock->type == WM_DOCK) {
  400.     if (aicon->dock->on_right_side)
  401.         x = scr->scr_width/2;
  402.     else
  403.         x = scr->scr_width/2 - PWIDTH;
  404.     } else {
  405.     x = (scr->scr_width - PWIDTH)/2;
  406.     }
  407.     panel->wwin = wManageInternalWindow(scr, parent, None,
  408.                     _("Docked Application Settings"),
  409.                     x, y, PWIDTH, PHEIGHT);
  410.  
  411.     panel->wwin->client_leader = WMWidgetXID(panel->win);
  412.  
  413.     panel->parent = parent;
  414.  
  415.     WMMapWidget(panel->win);
  416.  
  417.     wWindowMap(panel->wwin);
  418. }
  419.  
  420.  
  421. void
  422. DestroyDockAppSettingsPanel(AppSettingsPanel *panel)
  423. {
  424.     if (!panel->destroyed) {
  425.     XUnmapWindow(dpy, panel->wwin->client_win);
  426.     XReparentWindow(dpy, panel->wwin->client_win,
  427.             panel->wwin->screen_ptr->root_win, 0, 0);
  428.     wUnmanageWindow(panel->wwin, False, False);
  429.     }
  430.  
  431.     panel->destroyed = 1;
  432.  
  433.     /*
  434.      * kluge. If we destroy the panel before the icon chooser is closed,
  435.      * we will crash when it does close, trying to access something in the
  436.      * destroyed panel. Could use wretain()/wrelease() in the panel,
  437.      * but it is not working for some reason.
  438.      */
  439.     if (panel->choosingIcon)
  440.     return;
  441.  
  442.     WMDestroyWidget(panel->win);
  443.  
  444.     XDestroyWindow(dpy, panel->parent);
  445.  
  446.     panel->editedIcon->panel = NULL;
  447.  
  448.     panel->editedIcon->editing = 0;
  449.  
  450.     free(panel);
  451. }
  452.